package com.restaurantonlineorder.seller.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.restaurantonlineorder.response.BaseResult;
import com.restaurantonlineorder.response.BaseResultCode;
import com.restaurantonlineorder.seller.constant.DBFiledConstant;
import com.restaurantonlineorder.seller.domain.Goods;
import com.restaurantonlineorder.seller.domain.HorsemanOrder;
import com.restaurantonlineorder.seller.domain.Order;
import com.restaurantonlineorder.seller.domain.Store;
import com.restaurantonlineorder.seller.enums.GoodsState;
import com.restaurantonlineorder.seller.horseman.HorsemanOrderTest;
import com.restaurantonlineorder.seller.mapper.OrderMapper;
import com.restaurantonlineorder.seller.service.*;
import com.restaurantonlineorder.seller.vo.req.OrderReqVo;
import com.restaurantonlineorder.seller.vo.resp.OrderRespVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @author 熊宇
 * @date 2022/7/23 15:32
 * @description 订单 实现类
 */
@Service
@Slf4j
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements IOrderService {

    @Resource
    private IGoodsService igoodsService;

    @Resource
    private IStoreService iStoreService;

    @Resource
    private IUserService iUserService;


    @Resource
    private IHorsemanOrderService iHorseManOrderService;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @Resource
    private HorsemanOrderTest horsemanOrderTest;

    /**
     * 查看订单
     *
     * @param id 订单ID
     * @return
     */
    @Override
    public OrderRespVo getOrderInfo(Long id) {
        OrderRespVo orderRespVo = this.baseMapper.selectById(id);
        return orderRespVo;
    }

    /**
     * 生成订单
     *
     * @param orderReqVo 订单请求参数
     * @return
     */
    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public BaseResult createOrder(OrderReqVo orderReqVo) {
        LambdaQueryWrapper<Goods> queryWrapper = Wrappers.lambdaQuery(Goods.class);
        queryWrapper.select(Goods::getPrice, Goods::getQuantity, Goods::getGoodsName)
                .eq(Goods::getId, orderReqVo.getGoodsId());

        //订单商品数量
        Integer count = orderReqVo.getCount();

        Map<String, Object> map;
        BigDecimal sum = null;

        //修改商品库存个数
        synchronized (OrderServiceImpl.class) {
            map = this.igoodsService.getMap(queryWrapper);
            BigDecimal price = (BigDecimal) map.get(DBFiledConstant.PRICEFILEDAME);
            BigDecimal decimalCount = BigDecimal.valueOf(count);
            sum = price.multiply(decimalCount);
            Integer quantity = (Integer) map.get(DBFiledConstant.QUANTITYFILEDNAME);
            if (quantity >= count) {

                //扣款
                boolean deductIsSuccess = iUserService.deductMoney(orderReqVo.getBuyerId(), sum);
                if (deductIsSuccess) {
                    //存款
                    iUserService.earnMoney(orderReqVo.getSellerId(), sum);
                } else {
                    return BaseResult.failure(BaseResultCode.INSUFFICIENT_WALLET);

                }
                //剩余商品个数
                int surplus = quantity - count;
                LambdaUpdateWrapper<Goods> updateWrapper = Wrappers.lambdaUpdate(Goods.class);
                updateWrapper.set(Goods::getQuantity, surplus)
                        .eq(Goods::getId, orderReqVo.getGoodsId());
                //修改商品个数
                this.igoodsService.update(updateWrapper);
            } else {
                return BaseResult.failure(BaseResultCode.INSUFFICIENT_GOODS);
            }
        }

        Order order = new Order();
        order.setUserId(orderReqVo.getBuyerId());
        BeanUtils.copyProperties(orderReqVo, order);
        order.setMoney(sum);
        order.setCreatedTime(LocalDateTime.now());
        order.setGoodsState(GoodsState.PREPARING);

        //保存订单信息
        this.save(order);

        LambdaQueryWrapper<Store> storeQueryWrapper = Wrappers.lambdaQuery(Store.class);
        storeQueryWrapper.select(Store::getStoreName)
                .eq(Store::getId, orderReqVo.getStoreId());
        Map<String, Object> nameMap = this.iStoreService.getMap(storeQueryWrapper);
        String storeName = (String) nameMap.get(DBFiledConstant.STOREFILEDNANME);
        String goodsName = (String) map.get(DBFiledConstant.GOODSFILEDNAME);


        OrderRespVo orderRespVo = new OrderRespVo();
        orderRespVo.setStoreName(storeName);
        orderRespVo.setGoodsName(goodsName);
        BeanUtils.copyProperties(order, orderRespVo);

        //分配骑手
        dispatchHorseman(order.getId());

        return BaseResult.success(orderRespVo);
    }


    private void dispatchHorseman(Long id) {
        HorsemanOrder horsemanOrder = new HorsemanOrder();
        horsemanOrder.setOrderId(id)
                .setHorsemanId(1L);
        threadPoolExecutor.execute(() -> {
            iHorseManOrderService.createHorsemanOrder(horsemanOrder);

            //模拟商家准备商品
            try {
                TimeUnit.SECONDS.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            //选派骑手
            horsemanOrderTest.takeOrders(id);

        });
    }

}
